package vim.meet.javassist;

import javassist.bytecode.CodeAttribute;
import javassist.bytecode.LocalVariableAttribute;
import javassist.bytecode.MethodInfo;

import java.io.IOException;
import java.lang.reflect.Modifier;

public class CompileTimeClass {
    
    public static void main(String[] args) {
//        make();
        methodInfo();
    }
    
    public static void methodInfo(){
        Class<?> clazz = CompileTimeClass.class;
     // 实例化类型池  
        ClassPool classPool = ClassPool.getDefault();  
        classPool.appendClassPath(new ClassClassPath(clazz));  
        CtClass ctClass = null;
        try {
            ctClass = classPool.get(clazz.getName());
        } catch (NotFoundException e) {
            e.printStackTrace();
        }  
          
        // 获取方法  
        CtMethod method = null;
        try {
            method = ctClass.getDeclaredMethod("make");
        } catch (NotFoundException e) {
            e.printStackTrace();
        }  
        // 判断是否为静态方法  
        int staticIndex = Modifier.isStatic(method.getModifiers()) ? 0 : 1;
          
        // 获取方法的参数  
        MethodInfo methodInfo = method.getMethodInfo();
        System.out.println(methodInfo);
        CodeAttribute codeAttribute = methodInfo.getCodeAttribute();  
        System.out.println(codeAttribute);
        LocalVariableAttribute localVariableAttribute = (LocalVariableAttribute)codeAttribute.getAttribute(LocalVariableAttribute.tag);  
        System.out.println(localVariableAttribute);
        try {
            for (int i = 0; i < method.getParameterTypes().length; i++) {  
                System.out.println("第" + (i + 1) + "个参数名称为: " + localVariableAttribute.variableName(staticIndex + i));  
            }
        } catch (NotFoundException e) {
            e.printStackTrace();
        }
    }
    
    public static void make(){
        ClassPool pool = ClassPool.getDefault();
        CtClass cc = pool.makeClass("Point");
        try {
            CtMethod cm = CtNewMethod.make("public int sum(int a,int b){return a + b;}", cc);
            cm.insertBefore("System.out.println(\"sum begining...\");");
            cc.addMethod(cm);
        } catch (CannotCompileException e) {
            e.printStackTrace();
        }
        try {
            cc.writeFile();
        } catch (NotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (CannotCompileException e) {
            e.printStackTrace();
        }
    }
    
    public int sum(int a,int b){
        return a + b;
    }
    
    public static void modify(){
        ClassPool pool = ClassPool.getDefault();
        CtClass cc = null;
        try {
            cc = pool.get("cn.freemethod.bean.Rectangle");
        } catch (NotFoundException e) {
            e.printStackTrace();
        }
        try {
            cc.setSuperclass(pool.get("cn.freemethod.bean.Point"));
        } catch (CannotCompileException e) {
            e.printStackTrace();
        } catch (NotFoundException e) {
            e.printStackTrace();
        }
        try {
            cc.writeFile();
        } catch (NotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (CannotCompileException e) {
            e.printStackTrace();
        }
    }

}
